#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>

#define PRINT( x ) printf( # x ": %d\n", x )

void check_type( int fd )
{
	struct stat fs;

	if( fstat( fd, &fs ) != 0 ) {
		fprintf( stderr, "fstat fd %d error, errno %d\n", fd, errno );
		return;
	}
	/*
	   S_ISREG(m)  is it a regular file?
	   S_ISDIR(m)  directory?
	   S_ISCHR(m)  character device?
	   S_ISBLK(m)  block device?
	   S_ISFIFO(m) FIFO (named pipe)?
	   S_ISLNK(m)  symbolic link? (Not in POSIX.1-1996.)
	   S_ISSOCK(m) socket? (Not in POSIX.1-1996.)
	 */

	if( S_ISREG( fs.st_mode ) )
		printf( "fd %d is a regular file.\n", fd );
	if( S_ISDIR( fs.st_mode ) )
		printf( "fd %d directory.\n", fd );
	if( S_ISCHR( fs.st_mode ) )
		printf( "fd %d character device.\n", fd );
	if( S_ISBLK( fs.st_mode ) )
		printf( "fd %d block device.\n", fd );
	if( S_ISFIFO( fs.st_mode ) )
		printf( "fd %d FIFO (named pipe).\n", fd );
	if( S_ISLNK( fs.st_mode ) )
		printf( "fd %d symbolic link.\n", fd );
	if( S_ISSOCK( fs.st_mode ) )
		printf( "fd %d socket.\n", fd );
}

int main( int argc, char *argv[] )
{
	if( argc > 1 ) {
		for( int i = 1; i < argc; i++ )
			check_type( atoi( argv[i] ) );
		return 0;
	}

	check_type( -1 );
	check_type( 0 );
	check_type( 1 );
	check_type( 2 );
	check_type( 3 );
	return 0;
}

